package com.hxzy.filter;

import com.alibaba.fastjson.JSONObject;
import com.hxzy.util.RedisUtil;
import com.hxzy.util.StringUtil;
import com.hxzy.util.ThreadLocalUtil;
import com.hxzy.common.ResultAjax;
import com.hxzy.entity.UserInfo;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description:
 * @Author: ykj
 * @Date: 2022/3/4 15:13
 */
/**
 * 登录令牌判断拦截器
 * @Description:
 * @Author: hxzy
 * @Date: 2022/3/4 10:44
 */
@WebFilter(urlPatterns = "/*",initParams = {
        @WebInitParam(name = "exclude",value = ".js,.css,.png,.jpg,.gif,.icon,/captcha,/login,/select/business")
})
public class TokenValidatorFilter  implements Filter {

    //强引用数据类型
    private List<String> excludeArray=new ArrayList<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String excludeStr = filterConfig.getInitParameter("exclude");
        if (StringUtil.isNotBlank(excludeStr)){
            this.excludeArray= Arrays.asList(excludeStr.split(","));
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException {

            HttpServletRequest req=(HttpServletRequest)  servletRequest;
            HttpServletResponse resp = (HttpServletResponse) response;
        //取得当前访问地址url地址
        String url = req.getRequestURI();
        //放行
        if (isPass(url)){
            chain.doFilter(req, response);
        }else {
            //验证 登录的令牌是否有效了, 从请求头header中取，告诉前端人员，必须header中携带一个UserToken键
            String token = req.getHeader("UserToken");
            //为空
            if (StringUtil.isBlank(token)){
                this.render(resp, ResultAjax.error(50000,"未登录，请先登录"));
                return;
            }
            //不空，验证redis过期没有login_total
            String loginSuccessRedisKey="login_total:"+token;
            String redisValue= RedisUtil.create().get(loginSuccessRedisKey);
            if (StringUtil.isBlank(redisValue)){
                this.render(resp, ResultAjax.error(50001,"令牌无效"));
                return;
            }

            //把redis的值，转化java对象
            UserInfo userInfo=JSONObject.parseObject(redisValue, UserInfo.class);
            ThreadLocalUtil.threadLocal.set(userInfo);
            //放行
            chain.doFilter(servletRequest,resp);
        }

    }

    @Override
    public void destroy() {
        this.excludeArray.clear();
    }

    /**
     * 判断url地址是否可以放行
     * @param url
     * @return
     */
    private boolean isPass(String url){
        long count=excludeArray.stream().filter(s->url.lastIndexOf(s)>=0).count();
        return count>0;
    }

    /**
     * 向客户端输出字符串信息
     * @param resultAjax
     */
    protected void render(HttpServletResponse resp, ResultAjax resultAjax) throws IOException {
        //编码UTF-8
        resp.setCharacterEncoding("UTF-8");
        //格式为网页
        resp.setContentType("text/html;charset=UTF-8");
        //网页输出jsp内置对象(9个中的一个  out )
        PrintWriter out=resp.getWriter();
        out.print(JSONObject.toJSONString(resultAjax));
        out.flush();
        out.close();
    }

}
